package Persistencia;

import Datatypes.DataCompra;
import Datatypes.DataNotificacion;
import Datatypes.DataRegistro;
import Datatypes.PDate;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.List;

public class BDMPerfil {
    
    private static BDMPerfil instance = null;
    private BDMConexion ct = null; 
    private PreparedStatement ps = null;
    private ResultSet rs = null;

    //CONSTRUCTOR
    
    private BDMPerfil(){}
    
    //GETERS
    
    public static synchronized BDMPerfil getInstance(){
        
        if(instance == null){
            
            instance = new BDMPerfil();
        
        }
        
        return instance;
    
    }
    
    //SETERS
    
    public void setConexion(BDMConexion BDMC){
    
        this.ct = BDMC;
    
    }
    
    //FUNCIONES PROPIAS
    
    //AREA DE TRABAJO DE JONATHAN////////////////////////////////////////////////////////////////////////////////
    
    public List<String> getNicks() throws Exception{
    
        
        
        List<String> lista = new ArrayList();
        
        try{
        
            ps = ct.getConexion().prepareStatement("SELECT nick FROM clientes");
            rs = ps.executeQuery();
            
            while(rs.next()){
            
                lista.add(rs.getString(1));
            
            }
            
            ps = ct.getConexion().prepareStatement("SELECT nick FROM desarrolladores");
            rs = ps.executeQuery();
            
            while(rs.next()){
            
                lista.add(rs.getString(1));
            
            }
            
        }
        
        catch(Exception e){
        
            throw new Exception("<html><body>Error al obtener la lista de nicks!<br><br>Codigo de Error: BDMPGN<br>Mensaje: " + e.getMessage() + "</body></html>");
           
        }
        
        return lista;
    
    }
   
    public List<String> getEmails() throws Exception{
    
        
        
        List<String> lista = new ArrayList();
        
        try{
        
            ps = ct.getConexion().prepareStatement("SELECT email FROM clientes");
            rs = ps.executeQuery();
            
            while(rs.next()){
            
                lista.add(rs.getString(1));
            
            }
            
            ps = ct.getConexion().prepareStatement("SELECT email FROM desarrolladores");
            rs = ps.executeQuery();
            
            while(rs.next()){
            
                lista.add(rs.getString(1));
            
            }
            
        }
        
        catch(Exception e){
        
            throw new Exception("<html><body>Error al obtener la lista de nicks!<br><br>Codigo de Error: BDMPGN<br>Mensaje: " + e.getMessage() + "</body></html>");
           
        }
        
        return lista;
    
    }
    
    /**
     * Desarrollador: Jonathan Franco<br>
     * Esta funcion chequea que el mail y la contraseña sean correctos retornando<br>
     * true si son validos o false en caso contrario.
     * 
     * @param email
     * @param password
     * @return Boolean
     * @throws Exception 
     */
    public Boolean comprobarPassword(String email, String password) throws Exception{
    
        
        
        Boolean valido = false;
        
        try{
        
            Perfil p = buscarPerfilXEmail(email);
            
            
            
            String pass = p.getPassWord();
            
            if(pass.equals(password)){
            
                valido = true;
            
            }
        
        }
        
        catch(Exception e){
        
            throw e;
        
        }
        
        return valido;
    
    }
    
    /**
     * Desarrollador: Jonathan Franco<br>
     * Esta funcion recibe un Cliente y guarda sus datos en la base de datos.
     *
     */
    public void altaCliente(Cliente c) throws Exception{ //INSERTA UN CLIENTE
        
        
        
        try{
                        
            ps = ct.getConexion().prepareStatement("INSERT INTO clientes (nick, nombre, apellido, fechaNac, edad, email, imagen, pass) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
            ps.setString(1, c.getNick());
            ps.setString(2, c.getNombre());
            ps.setString(3, c.getApellido());
            ps.setString(4, c.getFNac().getSQLDate());
            ps.setInt(5, c.getEdad());
            ps.setString(6, c.getEmail());
            ps.setString(7, c.getImagen());
            ps.setString(8, c.getPassWord());
            ps.executeUpdate();
                
        }
        
        catch(Exception e){
        
            throw new Exception("El cliente ya existe en el sistema!");
            //throw new Exception("Error al dar de alta el cliente!.<br><br>Codigo de Error: BDMPAC<br>Mensaje: " + e.getMessage());
               
        }
        
    }
    
    /**
     * Desarrollador: Jonathan Franco<br>
     * Esta funcion recibe un Desarrollador y guarda sus datos en la base de datos.
     *
     */
    public void altaDesarrollador(Desarrollador d) throws Exception{
        
        
        
        try{
                        
            ps = ct.getConexion().prepareStatement("INSERT INTO desarrolladores (nick, nombre, apellido, fechaNac, edad, email, imagen, weblink, pass) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)");
            ps.setString(1, d.getNick());
            ps.setString(2, d.getNombre());
            ps.setString(3, d.getApellido());
            ps.setString(4, d.getFNac().getSQLDate());
            ps.setInt(5, d.getEdad());
            ps.setString(6, d.getEmail());
            ps.setString(7, d.getImagen());
            ps.setString(8, d.getWebLink());
            ps.setString(9, d.getPassWord());
            ps.executeUpdate();
                    
        }
        
        catch(Exception e){
            
            //throw new Exception("El desarrollador ya existe en el sistema!");
            throw new Exception("<html><body>Error al dar de alta el desarrollador!<br><br>Codigo de Error: BDMPAD<br>Mensaje: " + e.getMessage() + "</body></html>");
           
        }
        
    }
    
    /**
     * Desarrollador: Jonathan Franco<br>
     * Esta funcion verifica que la pareja Nick, Email no existan en el sistema.<br>
     * Retorna true si existe o false en caso contrario.
     *
     * @return Boolean
     */
    public Boolean existePerfil(String nick, String email) throws Exception{
    
        
        
        Boolean existe = false;
        
        try{
        
            ps = ct.getConexion().prepareStatement("select 1 from clientes where nick = ?");
            ps.setString(1, nick);
            rs = ps.executeQuery();
            
            if(rs.next()){
            
                existe = true;
                
            }
            
            else{
            
                ps = ct.getConexion().prepareStatement("select 1 from clientes where email = ?");
                ps.setString(1, email);
                rs = ps.executeQuery();
                
                if(rs.next()){

                    existe = true;

                }
                
                else{
            
                    ps = ct.getConexion().prepareStatement("select 1 from desarrolladores where nick = ?");
                    ps.setString(1, nick);
                    rs = ps.executeQuery();

                    if(rs.next()){

                        existe = true;

                    }
                    
                    else{
                    
                        ps = ct.getConexion().prepareStatement("select 1 from desarrolladores where email = ?");
                        ps.setString(1, email);
                        rs = ps.executeQuery();

                        if(rs.next()){

                            existe = true;

                        }
                    
                    }

                }
            
            }         
            
        }
        
        catch(SQLException e){
        
            throw new Exception("Error interno!.<br><br>Codigo de Error: BDMPEP<br>Mensaje: " + e.getMessage());
               
        }
        
        return existe;
    
    }
    
    /**
     * Desarrollador: Jonathan Franco<br>
     * Esta funcion verifica que el Nick exista en el sistema.<br>
     * Retorna true si existe o false en caso contrario.
     *
     * @return Boolean
     */
    public Boolean existeNick(String nick) throws Exception{
           
        Boolean existe = false;
        
        try{
        
            ps = ct.getConexion().prepareStatement("select 1 from clientes where nick = ?");
            ps.setString(1, nick);
            rs = ps.executeQuery();
            
            if(rs.next()){
            
                existe = true;
                
            }
            
            else{
            
                ps = ct.getConexion().prepareStatement("select 1 from desarrolladores where nick = ?");
                ps.setString(1, nick);
                rs = ps.executeQuery();

                if(rs.next()){

                    existe = true;

                }   
                
            }
            
        }
        
        catch(SQLException e){
        
            throw new Exception("Error interno!.<br><br>Codigo de Error: BDMPEN<br>Mensaje: " + e.getMessage());
               
        }
        
        return existe;
    
    }
    
    /**
     * Desarrollador: Jonathan Franco<br>
     * Esta funcion verifica que el Email exista en el sistema.<br>
     * Retorna true si existe o false en caso contrario.
     *
     * @return Boolean
     */
    public Boolean existeEmail(String email) throws Exception{
    
        
        
        Boolean existe = false;
        
        try{
        
            ps = ct.getConexion().prepareStatement("select 1 from clientes where email = ?");
            ps.setString(1, email);
            rs = ps.executeQuery();
            
            if(rs.next()){
            
                existe = true;
                
            }
            
            else{
            
                ps = ct.getConexion().prepareStatement("select 1 from desarrolladores where email = ?");
                ps.setString(1, email);
                rs = ps.executeQuery();

                if(rs.next()){

                    existe = true;

                }   
                
            }
            
        }
        
        catch(SQLException e){
        
            throw new Exception("Error interno!.<br><br>Codigo de Error: BDMPEE<br>Mensaje: " + e.getMessage());
               
        }
        
        return existe;
    
    }
    
    /**
     * 
     * Desarrollador: Jonathan Franco<br>
     * La funcion recibe un nick y retorna el perfil correspondiente.
     * Retorna un perfil, debido a que puede ser cliente o desarrollador debe<br>
     * castearse la salida.<br>
     * Lanza una excepción si el perfil buscado no se encuentra.
     * 
     * @return Perfil
     * @throws Exception 
     */
    public Perfil buscarPerfil(String nick) throws Exception{
    
        
        
        Perfil p = null;
        
        if(existeNick(nick)){
        
            
            
            try{

                ps = this.ct.getConexion().prepareStatement("SELECT * FROM clientes WHERE nick = ?");
                ps.setString(1, nick);
                rs = ps.executeQuery();
                
                if(rs.next()){
                
                    String password = rs.getString(8);
                    String nombre = rs.getString(2);
                    String apellido = rs.getString(3);
                    PDate fNac = new PDate(rs.getString(4));
                    Integer edad = rs.getInt(5);
                    String email = rs.getString(6);
                    String imagen = rs.getString(7);
                    
                    p = new Cliente(password, nick, nombre, apellido, edad, fNac, email, imagen);
                
                }
                
                else{
                
                    ps = this.ct.getConexion().prepareStatement("SELECT * FROM desarrolladores WHERE nick = ?");
                    ps.setString(1, nick);
                    rs = ps.executeQuery();
                    
                    String password = rs.getString(9);
                    String nombre = rs.getString(2);
                    String apellido = rs.getString(3);
                    PDate fNac = new PDate(rs.getString(4));
                    Integer edad = rs.getInt(5);
                    String email = rs.getString(6);
                    String imagen = rs.getString(7);
                    String weblink = rs.getString(8);

                    p = new Desarrollador(password, nick, nombre, apellido, edad, fNac, email, imagen, weblink);
                
                }

            }

            catch(SQLException e){

                throw new Exception("Error interno!.<br><br>Codigo de Error: BDMPBP<br>Mensaje: " + e.getMessage());

            }
        
        }
        
        else{
        
            throw new Exception("Error interno!.<br><br>Codigo de Error: BDMPBP<br>Mensaje: No existe el perfil!");

        }
        
        return p;
    
    }
    
    /**
     * 
     * Desarrollador: Jonathan Franco<br>
     * La funcion recibe un email y retorna el perfil correspondiente.
     * Retorna un perfil, debido a que puede ser cliente o desarrollador debe<br>
     * castearse la salida.<br>
     * Lanza una excepción si el perfil buscado no se encuentra.
     * 
     * @return Perfil
     * @throws Exception 
     */
    public Perfil buscarPerfilXEmail(String email) throws Exception{
    
        
        
        Perfil p = null;
        
        if(existeEmail(email)){
        
            
            
            try{

                ps = this.ct.getConexion().prepareStatement("SELECT * FROM clientes WHERE email = ?");
                ps.setString(1, email);
                rs = ps.executeQuery();
                
                if(rs.next()){
                
                    String password = rs.getString(8);
                    String nombre = rs.getString(2);
                    String apellido = rs.getString(3);
                    PDate fNac = new PDate(rs.getString(4));
                    Integer edad = rs.getInt(5);
                    String nick = rs.getString(1);
                    String imagen = rs.getString(7);
                    
                    p = new Cliente(password, nick, nombre, apellido, edad, fNac, email, imagen);
                
                }
                
                else{
                
                    ps = this.ct.getConexion().prepareStatement("SELECT * FROM desarrolladores WHERE email = ?");
                    ps.setString(1, email);
                    rs = ps.executeQuery();
                    
                    String password = rs.getString(9);
                    String nombre = rs.getString(2);
                    String apellido = rs.getString(3);
                    PDate fNac = new PDate(rs.getString(4));
                    Integer edad = rs.getInt(5);
                    String nick = rs.getString(1);
                    String imagen = rs.getString(7);
                    String weblink = rs.getString(8);

                    p = new Desarrollador(password, nick, nombre, apellido, edad, fNac, email, imagen, weblink);
                
                }

            }

            catch(SQLException e){

                throw new Exception("Error interno!.<br><br>Codigo de Error: BDMPBP<br>Mensaje: " + e.getMessage());

            }
        
        }
        
        else{
        
            throw new Exception("Error interno!.<br><br>Codigo de Error: BDMPBP<br>Mensaje: No existe el perfil!");
            
        }
        
        return p;
    
    }
    
    /**
     * 
     * Desarrollador: Jonathan Franco
     * La funcion modifica el perfil controlando que el nick y email<br>
     * cumplan la unicidad, en caso contrario lanza una excepcion.
     * 
     * @throws Exception 
     */
    public void actualizarPerfil(String oldnick, String oldemail, Perfil p) throws Exception{
        
        
        
        try{
        
            if(p instanceof Cliente){

                if(!(oldnick.equals(p.getNick()))){

                    if(existeNick(p.getNick())){

                        throw new Exception("El nick " + p.getNick() + " ya existe en el sistema.");

                    }
                        
                }

                if(!(oldemail.equals(p.getEmail()))){
                    
                    if(existeEmail(p.getEmail())){

                        throw new Exception("El email " + p.getEmail() + " ya existe en el sistema.");

                    }

                }

                Cliente c = (Cliente)p;
                
                
                
                ps = ct.getConexion().prepareStatement("UPDATE clientes SET nick = ?, nombre = ?, apellido = ?, fechaNac = ?, edad = ?, email = ?, imagen = ?, pass = ? WHERE nick = ? and email = ?");
                ps.setString(1, c.getNick());
                ps.setString(2, c.getNombre());
                ps.setString(3, c.getApellido());
                ps.setString(4, c.getFNac().getSQLDate());
                ps.setInt(5, c.getEdad());
                ps.setString(6, c.getEmail());
                ps.setString(7, c.getImagen());
                ps.setString(8, c.getPassWord());
                ps.setString(9, oldnick);
                ps.setString(10, oldemail);
                ps.executeUpdate();
                
                ps = ct.getConexion().prepareStatement("UPDATE comentarios_de_clientes SET nick_cliente = ? WHERE nick_cliente = ?");
                ps.setString(1, c.getNick());
                ps.setString(2, oldnick);
                ps.executeUpdate();

                ps = ct.getConexion().prepareStatement("UPDATE clientes_compran_juegos SET nick_cliente = ?, email_cliente = ? WHERE nick_cliente = ? AND email_cliente = ?");
                ps.setString(1, c.getNick());
                ps.setString(2, c.getEmail());
                ps.setString(3, oldnick);
                ps.setString(4, oldemail);
                ps.executeUpdate();

            }

            else{

                if(!(oldnick.equals(p.getNick()))){

                    if(existeNick(p.getNick())){

                        throw new Exception("El nick " + p.getNick() + " ya existe en el sistema.");

                    }
                        
                }

                if(!(oldemail.equals(p.getEmail()))){
                    
                    if(existeEmail(p.getEmail())){

                        throw new Exception("El email " + p.getEmail() + " ya existe en el sistema.");

                    }

                }

                Desarrollador d = (Desarrollador)p;
                
                
                
                ps = ct.getConexion().prepareStatement("UPDATE desarrolladores SET nick = ?, nombre = ?, apellido = ?, fechaNac = ?, edad = ?, email = ?, imagen = ?, weblink = ?, pass = ? WHERE nick = ? and email = ?");
                ps.setString(1, d.getNick());
                ps.setString(2, d.getNombre());
                ps.setString(3, d.getApellido());
                ps.setString(4, d.getFNac().getSQLDate());
                ps.setInt(5, d.getEdad());
                ps.setString(6, d.getEmail());
                ps.setString(7, d.getImagen());
                ps.setString(8, d.getWebLink());
                ps.setString(9, d.getPassWord());
                ps.setString(10, oldnick);
                ps.setString(11, oldemail);
                ps.executeUpdate();
                
                ps = ct.getConexion().prepareStatement("UPDATE desarrolladores_de_juegos SET nick_desarrollador = ? WHERE nick_desarrollador = ?");
                ps.setString(1, d.getNick());
                ps.setString(2, oldnick);
                ps.executeUpdate();
                
            }
            
        }
        
        catch(Exception e){
        
            throw new Exception("Error interno!.<br><br>Codigo de Error: BDMPAP<br>Mensaje: " + e.getMessage());

        }
    
    }
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    //AREA DE TRABAJO DE NACHO////////////////////////////////////////////////////////////////////////////////////
    
    public List<Perfil> listarPerfiles() throws Exception{     
        
        
        
        List<Perfil> listaP = null;
        String nick, nom, ap, email, imagen, weblink;
        Integer edad;
        PDate fechaNac;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT * FROM clientes "
                                   + "ORDER BY nick ");
            rs = ps.executeQuery();
            
            ps = ct.getConexion().prepareStatement("SELECT * "
                                   + "FROM desarrolladores "
                                   + "ORDER BY nick");
            ResultSet rsD = ps.executeQuery();
            
            listaP = new ArrayList();
            
            //Cargar los Clientes en la lista de Perfiles
            while(rs.next()){
                
                nick = rs.getString("nick");
                nom = rs.getString("nombre");
                ap = rs.getString("apellido");
                edad = rs.getInt("edad");
                email = rs.getString("email");
                imagen = rs.getString("imagen");
                fechaNac = new PDate(rs.getString("fechaNac"));
                Cliente c = new Cliente(nick, nom, ap, edad, fechaNac, email, imagen);
                listaP.add(c); 
            
            }
            
            while(rsD.next()){
                
                nick = rsD.getString("nick");
                nom = rsD.getString("nombre");
                ap = rsD.getString("apellido");
                edad = rsD.getInt("edad");
                email = rsD.getString("email");
                imagen = rsD.getString("imagen");
                fechaNac = new PDate(rsD.getString("fechaNac"));
                weblink  = rsD.getString("weblink");
                
                Desarrollador d = new Desarrollador
                                      (nick, nom, ap, edad, fechaNac, email, imagen, weblink);
                listaP.add(d); 
            }
               
            
        }catch(SQLException e){
            
            throw e;
            
        }
                
        return listaP;
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Consultar Perfil.<br>
     * Lista todos los Clientes existentes del sistema.<br>
     *
     * @return List<Clientes>
     */
    public List<Cliente> listarClientes() throws Exception{     
        
        
        
        List<Cliente> listaC = null;
        String nick, nom, ap, email, imagen;
        Integer edad;
        PDate fechaNac;
        //Cliente c = null;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT * FROM clientes "
                                   + "ORDER BY nick");
            rs = ps.executeQuery();
            listaC = new ArrayList();
            
            while(rs.next()){
                
                nick = rs.getString("nick");
                nom = rs.getString("nombre");
                ap = rs.getString("apellido");
                edad = rs.getInt("edad");
                email = rs.getString("email");
                imagen = rs.getString("imagen");
                fechaNac = new PDate(rs.getString("fechaNac"));
                Cliente c = new Cliente(nick, nom, ap, edad, fechaNac, email, imagen);
                listaC.add(c); 
            
            }
            
        }catch(SQLException e){
            
            throw e;
            
        }
        
        return listaC;
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Consultar Perfil.<br>
     * Lista todos los Desarrolladores existentes del sistema.<br>
     *
     * @return List<Desarrollador>
     */
    public List<Desarrollador> listarDesarrolladores() throws Exception{     
        
        
        
        List<Desarrollador> listaD = null;
        String nick, nom, ap, email, imagen, link;
        Integer edad;
        PDate fechaNac;
        Desarrollador d;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT * FROM desarrolladores "
                                   + " ORDER BY nick");
            rs = ps.executeQuery();
            listaD = new ArrayList();
            
            while(rs.next()){
                
                nick = rs.getString("nick");
                nom = rs.getString("nombre");
                ap = rs.getString("apellido");
                edad = rs.getInt("edad");
                email = rs.getString("email");
                imagen = rs.getString("imagen");
                fechaNac = new PDate(rs.getString("fechaNac"));
                link = rs.getString(8);
                d = new Desarrollador(nick, nom, ap, edad, fechaNac, email, imagen, link);
                listaD.add(d); 
            
            }
            
        }catch(SQLException e){
            
            throw e;
            
        }
        
        return listaD;
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Consultar Perfil.<br>
     * Devuelve el perfil de nick = nick y email = correo.<br>
     *
     * @return List<Desarrollador>
     */
    public Perfil elegirPerfil(String nick, String correo) throws Exception{
        
        Perfil p = null;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT * FROM clientes "
                                   + "WHERE nick = ? AND email = ?");
            ps.setString(1, nick);
            ps.setString(2, correo);
            rs = ps.executeQuery();
            
            if(rs.next()){
                
                p = new Cliente(nick, rs.getString(2), rs.getString(3), 
                        rs.getInt(5), new PDate(rs.getString(4)), correo, rs.getString(7));
            
            }else{
            
                ps = ct.getConexion().prepareStatement("SELECT * FROM desarrolladores "
                                       + "WHERE nick = ? AND email = ?");
                ps.setString(1, nick);
                ps.setString(2, correo);
                rs = ps.executeQuery();
                
                if(rs.next()){
                
                    p = new Desarrollador
                                   (nick, rs.getString(2), rs.getString(3), rs.getInt(5),
                                    new PDate(rs.getString(4)), correo, rs.getString(7),
                                    rs.getString(8));
                
                }
            
            }
            
        }catch(SQLException e){
            
            throw new Exception(e.getMessage() + "- ERROR en elegirPerfil");
            
        }
        
        return p;
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Alta Reclamo.<br>
     * Inserta una  categoria de reclamos en la tabla de 
     * categoria_de_reclamos.<br>
     *
     * @return List<Desarrollador>
     */
    public void altaCatReclamo(Categoria c) throws Exception{
    
        
        
        try{
                        
            ps = ct.getConexion().prepareStatement("INSERT INTO categoria_de_reclamos "
                 + "(id, nombre) VALUES (?, ?)");
            ps.setString(1, null);
            ps.setString(2, c.getNombre());
            ps.executeUpdate();
            
            ps = ct.getConexion().prepareStatement("SELECT id FROM categoria_de_reclamos "
                                   + "ORDER BY id DESC");
            rs = ps.executeQuery();
            
            if(rs.next()){
            
                c.setId(rs.getInt(1));

            }
                
        }
        
        catch(SQLException e){
        
            throw new Exception("La categoria no se pudo dar de alta!");
            //throw new Exception("Error al dar de alta el cliente!.<br><br>Codigo de Error: BDMPAC<br>Mensaje: " + e.getMessage());
               
        }
    
    }    
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Alta de reclamos.<br>
     * Devuelve la Categoria con identificador = id.<br>
     *
     * @return <Categoria>
     */    
    public Categoria getCategoria(Integer id) throws Exception{

        Categoria c = null;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT * FROM categoria_de_reclamos WHERE id = ?");
            ps.setInt(1, id);
            rs = ps.executeQuery();
            
            if(rs.next()){
            
                c = new Categoria(rs.getString("nombre"));
                c.setId(id);
                
            }else{
            
                return c;
            
            }
            
            
        }catch(SQLException e){
            
            throw new Exception("ERROR en listar las categoriade reclamos.");
            
        }
        
        return c;        
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Alta de reclamos.<br>
     * Lista todas las categorias del sistema para cargar un "<select>".<br>
     *
     * @return List<Categoria>
     */
    public List<Categoria> listarCategoriasReclamos() throws Exception{ 

        String nom;
        List<Categoria> lista = null;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT * FROM categoria_de_reclamos ORDER BY nombre");
            rs = ps.executeQuery();
            lista = new ArrayList();
            
            while(rs.next()){
                
                nom = rs.getString(2);
                Categoria cat = new Categoria(nom);
                cat.setId(rs.getInt(1));
                lista.add(cat); 
            
            }
            
        }catch(SQLException e){
            
            throw new Exception("ERROR en listar las categoriade reclamos.");
            
        }
        
        return lista;
    
    }    

    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Alta Reclamo.<br>
     * Devuelve el IdReclamo del ultimo reclamo r.<br>
     *
     * @return List<Desarrollador>
     */ 
    public Integer getIdReclamo(Reclamo r) throws Exception{
    
        
        
        Integer id = null;
        
        try{
        
            ps = ct.getConexion().prepareStatement("SELECT idReclamo FROM reclamos ORDER BY idReclamo DESC");
            rs = ps.executeQuery();
            
            if(rs.next()){
            
                id = rs.getInt("idReclamo");
                
            }
            
        }
        
        catch(SQLException e){
        
            throw new Exception("Error interno!.<br><br>Codigo de Error: BDMCGIDC<br>Mensaje: " + e.getMessage());
               
        }
        
        return id;
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Alta Reclamo.<br>
     * Inserta un reclamos en la tabla de reclamos.<br>
     *
     * @return List<Desarrollador>
     */
    public void altaReclamo(Reclamo r) throws Exception{
    
        
        
        try{
                        
            ps = ct.getConexion().prepareStatement("INSERT INTO reclamos "
                 + "(idReclamo, texto, fecha, idCategoria) VALUES (?, ?, ?, ?)");
            ps.setString(1, null);
            ps.setString(2, r.getTexto());
            ps.setString(3, r.getFecha().getSQLDate());
            ps.setInt(4, r.getIdCatReclamo());
            ps.executeUpdate();
            
            Integer id = getIdReclamo(r);
            r.setIdReclamo(id);
            
            ps = ct.getConexion().prepareStatement("INSERT INTO reclamos_de_juegos "
                 + "(idReclamo, codJuego, version, nick_cliente) VALUES (?, ?, ?, ?)");
            ps.setInt(1, id);
            ps.setInt(2, r.getJuego());
            ps.setDouble(3, r.getVersion());
            ps.setString(4, r.getNickCliente());  
            ps.executeUpdate();
            
        }
        
        catch(SQLException e){
        
            throw new Exception("El reclamo no se pudo dar de alta!: " + e.getMessage());
            //throw new Exception("Error al dar de alta el cliente!.<br><br>Codigo de Error: BDMPAC<br>Mensaje: " + e.getMessage());
               
        }
    
    } 
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Ver Reclamo.<br>
     * Lista los reclamos de juego, para cargar en un "<select>".<br>
     *
     * @return List<Reclamo>
     */
    public List<Reclamo> listarReclamos(Integer codJuego) throws Exception{
    
        
        
        List<Reclamo> listaR = null;
        String texto, nickCli;
        Double version;
        Integer id, idCat, codJ;
        PDate fecha;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT r.idReclamo, r.texto, r.fecha, "
                                    + "r.idCategoria, rj.version, rj.nick_cliente, rj.codJuego "
                                    + "FROM reclamos_de_juegos rj, reclamos r "
                                    + "WHERE codJuego = ? AND rj.idReclamo = r.idReclamo "
                                    + "ORDER BY fecha DESC");
            
            ps.setInt(1, codJuego);
            rs = ps.executeQuery();
            
            listaR = new ArrayList<>();
            
            while(rs.next()){
                
                id = rs.getInt("idReclamo");
                texto = rs.getString("texto");
                nickCli = rs.getString("nick_cliente");
                version = rs.getDouble("version");
                fecha = new PDate(rs.getString("fecha"));
                idCat = rs.getInt("idCategoria");
                codJ = rs.getInt("codJuego");
                Reclamo r = new Reclamo(id, nickCli, texto, fecha, codJ, idCat, version);
                listaR.add(r); 
            
            }
            
        }catch(SQLException e){
            
            throw new Exception("Error en la obtencion de reclamos: "+e.getMessage());
            
        }
                
        return listaR;       
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Eliminar Juego.<br>
     * Elimina todos los reclamos del juego.<br>
     *
     * @return void
     */
    public void eliminarReclamosJuego(Integer codJuego) throws Exception{
        
        try{
            
            List<Reclamo> reclamos = this.listarReclamos(codJuego);
                        
            if(reclamos.size()  >  0){
                
                for(Reclamo r : reclamos){
                    
                    ps = ct.getConexion().prepareStatement("DELETE FROM reclamos WHERE idReclamo = ? ");
                    ps.setInt(1, r.getIdReclamo());
                    ps.executeUpdate();
                    
                }
                ps = ct.getConexion().prepareStatement("DELETE FROM reclamos_de_juegos WHERE codJuego = ?");
                ps.setInt(1, codJuego);
                ps.executeUpdate();
            }
        
        }
        
        catch(SQLException e){
            
            throw new Exception("Los reclamos no se pudieron dar de baja: "+e.getMessage());
               
        }
             
    }
 
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Ver Estadisticas.<br>
     * Carga los datos de la Estadistica a Graficar.<br>
     *
     * @return Estadistica
     */
    public Estadistica obtenerEstadisticaPIE(String nickD) throws Exception{
    
        Estadistica es = null;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT ccj.codigo_juego, ccj.nombre_juego, SUM(ccj.precio_juego) as ganancia " 
                                                 + "FROM clientes_compran_juegos ccj " 
                                                 + "WHERE nick_desarrollador = ? " 
                                                 + "GROUP BY ccj.codigo_juego");
            ps.setString(1, nickD);
            rs = ps.executeQuery();
            //if(rs.next()){
                DecimalFormat df = new DecimalFormat("0.00");
                es = new Estadistica(nickD);
                while(rs.next()){
                    
                    es.getDatosX().add(rs.getInt(1) + " - " + rs.getString(2));
                    es.getDatosY().add(Double.parseDouble(df.format((rs.getDouble(3))).replace(",", ".")));
            
                }
                es.getOp().add("Ganancias por Juegos de: " + nickD);
                es.getOp().add("400");
                es.getOp().add("300");
                
            //}
            
        }catch(SQLException e){

            throw new Exception("Error en obtener Estadisticas PIE: "+e.getMessage());
            
        }

        return es;
    
    }
    
    
    public List<DataCompra> getComprasXDesarrollador(String nickD) throws Exception{
    
        List<DataCompra> listaC = new ArrayList();
        
        GregorianCalendar fecha = new GregorianCalendar();
        
        try{
            
            Integer hrs = fecha.get(GregorianCalendar.HOUR);
            Integer min = fecha.get(GregorianCalendar.MINUTE);
            Integer seg = fecha.get(GregorianCalendar.SECOND);
            
            Integer dia = fecha.get(GregorianCalendar.DAY_OF_MONTH);
            Integer mes = fecha.get(GregorianCalendar.MONTH) + 1;
            Integer anio = fecha.get(GregorianCalendar.YEAR) - 1;
            String f2 = "" + anio + "-" + mes + "-" + dia + " " + hrs + ":" + min + ":" + seg; 

            ps = ct.getConexion().prepareStatement(""
                    + "SELECT nick_cliente, email_cliente, fecha, codigo_juego, nombre_juego, nick_desarrollador, precio_juego "
                    + "FROM clientes_compran_juegos " 
                    + "WHERE (nick_desarrollador = ? "
                    + "AND fecha >= ? )");
            
            ps.setString(1, nickD);
            ps.setString(2, f2);
            
            rs = ps.executeQuery();
            
            while(rs.next()){
            
                DataCompra dc = new DataCompra(new PDate(rs.getString(3)), 
                                    rs.getString(1), rs.getString(5), rs.getString(6), rs.getDouble(7));
                listaC.add(dc);
            
            }
            
            //if(listaC.isEmpty()){ return null; }
            
        }catch(SQLException e){
            
            throw new Exception("Error en getComprasXDesarrollador: "+e.getMessage());
            
        }    
        
        return listaC;
    
    }
    
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    //AREA DE TRABAJO DE DIEGO////////////////////////////////////////////////////////////////////////////////////
    
    public void agregarCompra(Compra c) throws Exception{
        
        
        
        try{
            
            Juego j = c.getJuego();
            ps = this.ct.getConexion().prepareStatement("INSERT INTO clientes_compran_juegos(nick_cliente, email_cliente, fecha, codigo_juego, nombre_juego, nick_desarrollador, precio_juego)"
                    + " VALUES(?,?,?,?,?,?,?)");
            ps.setString(1, c.getCliente().getNick());
            ps.setString(2, c.getCliente().getEmail());
            ps.setString(3, c.getFecha().getSQLDate());
            ps.setInt(4, j.getCodigo());
            ps.setString(5, j.getNombre());
            ps.setString(6, j.getDesarrollador().getNick());
            ps.setDouble(7, j.getPrecio());
            
            ps.executeUpdate();
            
        }
        catch(SQLException e){
            
            throw new Exception(e.getMessage());
            
        }
            
    }
    
    //diego
    public Cliente buscarCliente(String nickCliente) throws Exception{ //busco, construyo, retorno
        
        
        
        Cliente c = null;
        try {
            
            ps = this.ct.getConexion().prepareStatement("SELECT * FROM clientes WHERE nick = ?");
            ps.setString(1, nickCliente);
            ResultSet query = ps.executeQuery();
            while(query.next()){
                c = new Cliente(query.getString(1), query.getString(2), query.getString(3),
                                query.getInt(5), new PDate(query.getString(4)), query.getString(6),
                                query.getString(7));
            }
            
        }
        
        catch (SQLException e) {
            
            throw e;
            
        }
        
        return c;
        
    }
    
    //diego
    public Desarrollador buscarDesarrollador(String nick) throws Exception{ //diego
        
        
        
        Desarrollador desarrollador = null;
        try{
            
            ps= this.ct.getConexion().prepareStatement("SELECT * FROM desarrolladores WHERE nick = ?");
            ps.setString(1, nick);
            ResultSet query = ps.executeQuery();
            while(query.next()){
                
                desarrollador = new Desarrollador(query.getString(1), query.getString(2), query.getString(3), query.getInt(5),
                                                  new PDate(query.getString(4)), query.getString(6), query.getString(7), query.getString(8));
                
            }
         
        }
        
        catch(SQLException e){
            
            throw e;
            
        }
        
        return desarrollador;
        
    }
    
        
    /**
     * Desarrollador: Diego<br>
     * Devuelve la lista de juegos comprados por un cliente.<br>
     * El string contiene el ID del juego concaternado
     *
     * @return List<String>
     */
    public List<String> juegosCompradosxCliente(String nick_cliente) throws Exception{
        
        
        
        List<String> lista = new ArrayList();
        try{
            
            ps= ct.getConexion().prepareStatement("SELECT j.nombre, j.codigo FROM juegos j, clientes_compran_juegos c "
                    + " WHERE j.codigo = c.codigo_juego AND c.nick_cliente = ? ");
            ps.setString(1, nick_cliente);
            ResultSet query =  ps.executeQuery();
            while(query.next()){
                
                String juego = query.getString(2)+"- "+query.getString(1);
                lista.add(juego);
                
            }
            
            
        }
        catch(SQLException e){
            
            throw new Exception("Hubo un problema al obtener los juegos del cliente: "+e.getMessage());
            
        }
                
        return lista;
    }
    
        /**
     * Desarrollador: Diego<br>
     * Chequea si el cliente compro el juego<br>
     * True si lo compro, false si no lo compro.
     * 
     * @param String nick_cliente
     * @param String codigo_juego
     * @return Boolean
     * @throws Exception 
     */
    public Boolean clienteComproJuego(String nick_cliente, Integer codigo_juego) throws Exception{
        
        
        
        Boolean compro = false;
        try{
           
            ps=ct.getConexion().prepareStatement("SELECT 1 FROM clientes_compran_juegos WHERE codigo_juego = ? AND nick_cliente = ? ");
            ps.setInt(1, codigo_juego);
            ps.setString(2, nick_cliente);
            ResultSet query = ps.executeQuery();
            if(query.next()){
                
                compro = true;
                                
            }
            
            return compro;
        }
        catch(SQLException e){
            
            throw new Exception("Hubo un problema al determinar si el cliente compro el juego: "+e.getMessage());
            
        }
        
    }
    
            /**
     * Desarrollador: Diego<br>
     * 
     * Ingresa el registro, si hay mas de 10k -> borra todos los registros con mayor a 30 dias, sino no ingresa.
     * 
     * @param Registro R
     * @return Boolean
     * @throws Exception 
     */
    public void ingresarRegistro(Registro R) throws Exception{
        
        
        
        try{
          
            int cantidad_registros = 0;
            ps = ct.getConexion().prepareStatement("SELECT count(*) AS regs FROM juegos");
            ResultSet query = ps.executeQuery();
            while(query.next()){
                
                cantidad_registros = query.getInt("regs");
                
            }
            
            if(cantidad_registros > 10000){
                
                ps = ct.getConexion().prepareStatement("DELETE FROM registros WHERE JULIANDAY(Date('now')) - JULIANDAY(fecha) > 30");
                ps.executeUpdate();
                
                ps = ct.getConexion().prepareStatement("SELECT count(*) AS regs FROM juegos");
                query = ps.executeQuery();
                while(query.next()){
                
                    cantidad_registros = query.getInt("regs");
                
                }
                if(cantidad_registros<10000){
                    
                    ps = ct.getConexion().prepareStatement("INSERT INTO registros (ip, navegador, fecha, id, url) VALUES (?,?,?,?,?)");
                    ps.setString(1, R.getIp());
                    ps.setString(2, R.getNavegador());
                    ps.setString(3, R.getFecha().getSQLDate());
                    ps.setString(4, null);
                    ps.setString(5, R.getUrl());
                    ps.executeUpdate();
                    
                }
            }
            else{
                
                ps = ct.getConexion().prepareStatement("INSERT INTO registros (ip, navegador, fecha, id, url) VALUES (?,?,?,?,?)");
                ps.setString(1, R.getIp());
                ps.setString(2, R.getNavegador());
                ps.setString(3, R.getFecha().getSQLDate());
                ps.setString(4, null);
                ps.setString(5, R.getUrl());
                ps.executeUpdate();

                
            }
            
        }
        catch(SQLException e){
            
            throw new Exception("Error con el ingreso de registro: "+e.getMessage());
        }
        
    }
    
    /**
     * Desarrollador: Diego<br>
     * 
     * Lista todos los registros
     * 
     * @param Registro R
     * @return Boolean
     * @throws Exception 
     */
    public List<DataRegistro> listarRegistros() throws Exception{
        
        
        
        List<DataRegistro> lista = new ArrayList();
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT * FROM registros");
            ResultSet query = ps.executeQuery();
            while(query.next()){
                
                DataRegistro dr = new DataRegistro(query.getString("ip"), query.getString("navegador"), new PDate(query.getString("fecha")), query.getString("url"));
                lista.add(dr);
                
            }
            
        }
        catch(SQLException e){
            
            throw new Exception("Error con la obtencion de registros: "+e.getMessage());
            
        }
        
        return lista;
    }
        
    public void notificarCliente(String nick_cliente, Integer codigo_juego) throws Exception{
        
        try{
            
            ps = ct.getConexion().prepareStatement("UPDATE notificaciones SET notificado = 1 WHERE nick_cliente = ? AND codigo_juego = ?");
            ps.setString(1, nick_cliente);
            ps.setInt(2, codigo_juego);
            ps.executeUpdate();
            
        }
        catch(SQLException e){
            
            throw new Exception("Hubo un error al notificar el cliente: BDMP: "+e.getMessage());
            
        }
    }
    
    
    public List<DataNotificacion> listarNotificacionesNuevas(String nick_cliente) throws Exception{
        
        List<DataNotificacion> lista = new ArrayList();
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT * FROM notificaciones WHERE nick_cliente = ? AND notificado = ?");
            ps.setString(1, nick_cliente);
            ps.setBoolean(2, false);
            ResultSet query = ps.executeQuery();
            while(query.next()){
                
                DataNotificacion dn = new DataNotificacion(query.getInt("codigo_juego"), null, query.getDouble("version"), query.getBoolean("notificado"), query.getInt("id"));
                lista.add(dn);
            
            }
            
        }
        catch(SQLException e){
            
            throw new Exception("Error al obtener las notificaciones nuevas: "+e.getMessage());
            
        }
        
        return lista;
    }
    
    public void borrarNotificacion(Integer id) throws Exception{
        try{
            
            ps = ct.getConexion().prepareStatement("DELETE FROM notificaciones WHERE id = ?");
            ps.setInt(1, id);
            ps.executeUpdate();
            
        }
        catch(Exception e){
            
            throw new Exception("Error al borrar la notificacion: "+e.getMessage());
            
        }
        
    }
        
}
    
    